﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Data;
using System.Data.SqlClient;
using System.IO;
using Tema2_Adabd.DataLayer;

namespace Tema2_Adabd.BusinessLayer
{
    public partial class Utilizator
    {
        public List<string> permisiuni;
        static private AccesBazaDeDate abd;
        public string numeUtilizator { private set; get; }

        static public Utilizator guest()
        {
            List<string> permisiuni = new List<string>{ "vizualizare_produse", "printare_produse"};
            abd = new AccesBazaDeDate();

            return new Utilizator(permisiuni);
        }

        private Utilizator(List<string> permisiuni,string nume="Guest")
        {
            this.permisiuni = permisiuni;
            numeUtilizator = nume;
        }

        //Modul de logare.
        static public Utilizator autentificaUtilizator(string nume, string parola)
        {
            if(abd==null)
                abd = new AccesBazaDeDate();

            string hash = abd.hashulParolei(nume);

            if (PasswordHash.ValidatePassword(parola,hash)== false )
            {
                throw new KeyNotFoundException();
            }

            List<string> perm = abd.autentificaUtilizator(nume,hash);
            if (perm.Count == 0)
                return null;

            Utilizator utilizator = new Utilizator(perm,nume);
            
            Utilizator.abd.recordOperation("recordOperation", "-","autentificare",DateTime.Now);

            return utilizator;
        }

        public void creeazaUtilizator(string nume, string parola)
        {
            //string s = PasswordHash.CreateHash(parola);
            //if (PasswordHash.ValidatePassword(parola, s) == false)
            //{
            //    throw new KeyNotFoundException();
            //}

            Utilizator.abd.creeazaUtilizator(nume,parola,this.numeUtilizator);
        }

        public void adaugaPermisiuni(string nume_user,string[] permisiuni)
        {
            int idUser = Utilizator.abd.userID(nume_user);

            foreach (var p in permisiuni)
            {
                int id_permisiune = Utilizator.abd.permisiuneID(p);

                Utilizator.abd.adaugaPermisiuni(id_permisiune,idUser);
            }
        }

        public bool numeUtilizatorExistent(string nume)
        {
            return Utilizator.abd.numeExistent(nume);
        }

        public void stergeUtilizator(string nume)
        {
            Utilizator.abd.stergeUtilizator(nume,this.numeUtilizator);
            recordDelete("Utilizatori");
        }


        //Modulul produs.
        public void adaugaProdus(string[] detaliiProdus)
        {
            byte[] photo = GetPhoto(detaliiProdus[8]);

            if (detaliiProdus[7] != "null")
            {
                int id_parinte = Utilizator.abd.daprodusID(detaliiProdus[7]);

                Utilizator.abd.adaugaProdus(int.Parse(detaliiProdus[2]), detaliiProdus[0], int.Parse(detaliiProdus[3]), photo, detaliiProdus[4],
                    detaliiProdus[5], detaliiProdus[1], decimal.Parse(detaliiProdus[6]), 1, id_parinte, this.numeUtilizator);
            }
            else
                Utilizator.abd.adaugaProdus(int.Parse(detaliiProdus[2]), detaliiProdus[0], int.Parse(detaliiProdus[3]), photo, detaliiProdus[4],
                    detaliiProdus[5], detaliiProdus[1], decimal.Parse(detaliiProdus[6]), 1, 0, this.numeUtilizator);
        }

        public bool existaCod(string codUnic)
        {
            return Utilizator.abd.existaCodUnic(int.Parse(codUnic));
        }

        public List<string> branduriExistente()
        {
            return Utilizator.abd.branduri();
        }

        public static byte[] GetPhoto(string filePath)
        {
            FileStream stream = new FileStream(
                filePath, FileMode.Open, FileAccess.Read);
            BinaryReader reader = new BinaryReader(stream);

            byte[] photo = reader.ReadBytes((int)stream.Length);

            reader.Close();
            stream.Close();

            return photo;
        }

        public void salveazaEditari(string numeProdus, string[] detaliiProdus, bool[] modificari)
        {
            byte[] photo = GetPhoto(detaliiProdus[8]);

            int id_parinte = Utilizator.abd.daprodusID(detaliiProdus[7]);

            Utilizator.abd.salveazaColoane(numeProdus, detaliiProdus[0],int.Parse(detaliiProdus[2]), int.Parse(detaliiProdus[3]), photo, detaliiProdus[4],
                detaliiProdus[5], detaliiProdus[1], decimal.Parse(detaliiProdus[6]), 1, id_parinte, this.numeUtilizator);
        }


        public bool produsExistentInBazaDeDate(string numeProdus)
        {
            return Utilizator.abd.produsExistentInBazaDeDate(numeProdus);
        }

        public void stergeTemporarProdusul(string numeProdus)
        {
            Utilizator.abd.stergeTemporarProdusul(numeProdus,this.numeUtilizator);
        }

        public void stergeDefinitivProdusul(string numeProdus)
        {
            Utilizator.abd.stergeDefinitivProdusul(numeProdus,numeUtilizator);
            recordDelete("Produse");
        }

        public List<Produse> cautaProdus(string numeProdus)
        {
            if (Utilizator.abd.produsExistentInBazaDeDate(numeProdus) == false)
                return null;

            return Utilizator.abd.cautaProdus(numeProdus);
        }

        public List<Produse> toateProdusele()
        {
            return Utilizator.abd.toateProdusele();
        }

        public List<Produse> filtrareDupaPret(decimal inf,decimal sup)
        {
            return Utilizator.abd.filtrareProduseDupaPret(inf,sup);
        }

        public List<Produse> produseFiltrate(string filtru,string valoareFiltru)
        {
            List<Produse> produse=new List<Produse>();

            switch(filtru)
            {
                case "nume_produs":
                    produse= Utilizator.abd.filtrareDupaNume(valoareFiltru);
                    break;
                case "brand":
                    produse = Utilizator.abd.filtrareDupaBrand(valoareFiltru);
                    break;
                case "stoc":
                    produse = Utilizator.abd.filtrareDupaStoc(int.Parse(valoareFiltru));
                    break;
                case "cod":
                    produse = Utilizator.abd.filtrareDupaCod(int.Parse(valoareFiltru));
                    break;
                case "produse sterse temporar":
                    produse = Utilizator.abd.filtrareProduseSterseTemporar();
                    break;
                default:throw new Exception("Filtru nespecificat.");
            }
            return produse;
        }


        public List<Produse> produseSortate(string SortExpr,string SortDir)
        {
            return Utilizator.abd.produseSortate(SortExpr,SortDir);
        }

        public void adaugaBrand(string brand)
        {
            Utilizator.abd.adaugaBrand(brand, this.numeUtilizator);
        }

        public void stergeBrand(string brand)
        {
            Utilizator.abd.stergeBrand(brand, this.numeUtilizator);
            recordDelete("Brand");
        }

        public void adaugaCategorie(string categorie)
        {
            Utilizator.abd.adaugaCategorie(categorie, this.numeUtilizator);
        }

        public void stergeCategorie(string categorie)
        {
            Utilizator.abd.stergeCategorie(categorie, this.numeUtilizator);
            recordDelete("Categorii");
        }

        private void recordDelete(string obiect)
        {
            Utilizator.abd.recordOperation("recordOperation",obiect, this.numeUtilizator,DateTime.Now);
        }

        public List<string> daCats()
        {
            return Utilizator.abd.daCats();
        }

        public bool isAdmin()
        {
            foreach (var v in permisiuni)
                if (v == "creare utilizatori")
                    return true;
            return false;
        }

        //public DataTable daAudit()
        //{
        //    return Utilizator.abd.tabelAudit();
        //}

        public void addCatProd(string numeProdus, string numeCategorie)
        {
            int idProdus = Utilizator.abd.daprodusID(numeProdus);
            int idCategorie = Utilizator.abd.daCategorieID(numeCategorie);

            Utilizator.abd.addCategoriileProdusului(idProdus,idCategorie);
        }

        public bool numeProdusExistent(string numeProdus)
        {
            return Utilizator.abd.numeProdusExistent(numeProdus);
        }

    }
}
